if (typeof(ko.extensions.webos.json) == 'undefined')
    ko.extensions.webos.json = {};

ko.extensions.webos.json.clearEditArea = function()
{
    var outputId = ko.extensions.webos.json.temp.id;
    while(document.getElementById(outputId).childNodes.length)
        document.getElementById(outputId).removeChild(document.getElementById(outputId).childNodes[0]);
};

ko.extensions.webos.json.getObject = function()
{
    ko.extensions.webos.json.processInputs(
        ko.extensions.webos.json.temp.data,
        ko.extensions.webos.json.temp.edit
        );
    return ko.extensions.webos.json.temp.data;
};

ko.extensions.webos.json.getString = function()
{
    ko.extensions.webos.json.processInputs(
        ko.extensions.webos.json.temp.data,
        ko.extensions.webos.json.temp.edit
        );
    return ko.extensions.webos.json.toString(ko.extensions.webos.json.temp.data);
};

ko.extensions.webos.json.toString = function(obj)
{
    var nativeJSON = Components.classes["@mozilla.org/dom/json;1"].createInstance(Components.interfaces.nsIJSON); 
    var s = nativeJSON.encode(obj);
    var sa = s.split("");
    var t = true;
    var q = true; // counts quotes
    var indent = 0;
    for(var i = 0; i < sa.length; i++)
    {
        if(sa[i].match(/\{|\[|,/))
        {
            if(sa[i].match(/\{|\[/))
                indent++;
            if(q == true)
            {
                sa.splice(i + 1, 0, "\n");
                for(var x = 0; x < indent; x++)
                    sa.splice(i + 2, 0, " "," "," "," ");
                i += (2 * indent) + 1;
                t = true;
            }
            else if(!sa[i].match(/,/))
            {
                q = true;
            }
        }
        else if(sa[i].match(/\}|\]/))
        {
            indent--;
            for(var x = 0; x < indent; x++)
                sa.splice(i, 0, " "," "," "," ");
            sa.splice(i, 0, "\n");
            if(indent == -1)
                break;
            i += (4 * indent) + 1;
            t = true;
        }
        else if(sa[i].match(/:/))
        {
            if(t)
            {
                sa.splice(i + 1, 0, " ");
                t = false;
                i++;
            }
        }
        if(sa[i].match(/"/) && !sa[i - 1].match(/\\/))
            q = !q;
        if(sa[i].match(/\n/))
        {
            t = true;
            sa.splice(i + 1, 0, "\n");
            for(var x = 0; x < indent; x++)
                sa.splice(i + 1, 0, " "," "," "," ");
            i += (2 * indent) + 1;
        }
    }
    return sa.join("");
};

ko.extensions.webos.json.processInputs = function(data, edit)
{
    for(var i in data)
    {
        var id = edit.ns + "_" + i;
        if(id == "webosTemp_version")
        {
            var n = ["major", "minor", "build"];
            var v = [];
            for(var x in n)
            {
                v[x] = parseFloat(document.getElementById(id + "_" + n[x]).value);
            }
            data[i] = v.join(".");
        }
        else if(typeof(data[i]) == "string")
        {
            data[i] = document.getElementById(id).value;
        }
        else if(typeof(data[i]) == "number")
        {
            data[i] = parseFloat(document.getElementById(id).value);
        }
        else if(typeof(data[i]) == "boolean")
        {
            if(document.getElementById(id).value == "true")
                data[i] = true;
            else
                data[i] = false;
        }
        else if(typeof(data[i]) == "object")
        {
            ko.extensions.webos.json.processInputs(data[i], edit[i]);
        }
    }
};

ko.extensions.webos.json.createEditArea = function(outputId, path)
{
    ko.extensions.webos.json.temp = {
        data:{},
        edit:{"ns":"webosTemp"},
        id:outputId
    };
    var ioService = Components.classes["@mozilla.org/network/io-service;1"]
                    .getService(Components.interfaces.nsIIOService);
    var uri = ioService.newURI(path, null, null);  
    var channel = ioService.newChannelFromURI(uri);
    var listener = channel.notificationCallbacks = {
        mData: "",
        onStartRequest: function (aRequest, aContext) {
            this.mData = "";
        },
        onDataAvailable: function (aRequest, aContext, aStream, aSourceOffset, aLength) {  
            var scriptableInputStream = 
            Components.classes["@mozilla.org/scriptableinputstream;1"]  
             .createInstance(Components.interfaces.nsIScriptableInputStream);  
            scriptableInputStream.init(aStream);
            this.mData += scriptableInputStream.read(aLength);  
        },
        onStopRequest: function (aRequest, aContext, aStatus)
        {
            if (Components.isSuccessCode(aStatus))
            {
                var nativeJSON = Components.classes["@mozilla.org/dom/json;1"].createInstance(Components.interfaces.nsIJSON);  
                ko.extensions.webos.json.temp.data = nativeJSON.decode(this.mData);
                // Clear Elements
                while(document.getElementById(outputId).childNodes.length)
                    document.getElementById(outputId).removeChild(document.getElementById(outputId).childNodes[0]);
                // Write appinfo.json with inputs and selects
                ko.extensions.webos.json.createInputs(ko.extensions.webos.json.temp.data, ko.extensions.webos.json.temp.edit);
            }
            else
            {
                alert("Error: Could not read template newproject.json");
            }
        }
    };
    channel.asyncOpen(listener, null);
};
ko.extensions.webos.json.versionToObject = function(version)
{
    var v = version.split(/\./);
    return {
        major:v[0],
        minor:v[1],
        build:v[2]
    };
};
ko.extensions.webos.json._objIndent = 0;
ko.extensions.webos.json.createInputs = function(data, edit)
{
    var container = ko.extensions.webos.json.temp.id;
    var namespace = ko.extensions.webos.json.temp.edit.ns;
    for(var i in data)
    {
        edit[i] = {};
        var indChar = "";
        for(var j = 0; j < ko.extensions.webos.json._objIndent; j++)
            indChar += String.fromCharCode(8250) + "  ";
        var ind = ko.extensions.webos.json._objIndent * 10;
        var id = edit.ns + "_" + i;
        if(id == namespace + "_version")
        {
            var w = 110 + ind;
            var n = ["major", "minor", "build"];
            var v = data[i].split(/\./);
            var hbox = document.createElement("hbox");
            hbox.setAttribute("flex", "1");
            hbox.setAttribute("align", "center");
            hbox.setAttribute("style", "border-bottom:1px solid #FFFFFF;border-top:1px solid #D4D4D4;");
            var label = document.createElement("label");
            label.setAttribute("style", "height:15px;width:" + w + "px;");
            label.setAttribute("value", "version");
            hbox.appendChild(label);
            var textbox_major = document.createElement("textbox");
            textbox_major.setAttribute("type", "number");
            textbox_major.setAttribute("value", v[0]);
            textbox_major.setAttribute("min", "0");
            textbox_major.setAttribute("max", "99");
            textbox_major.setAttribute("flex", "1");
            textbox_major.setAttribute("id", id + "_" + n[0]);
            hbox.appendChild(textbox_major);
            var textbox_minor = document.createElement("textbox");
            textbox_minor.setAttribute("type", "number");
            textbox_minor.setAttribute("value", v[1]);
            textbox_minor.setAttribute("min", "0");
            textbox_minor.setAttribute("max", "99");
            textbox_minor.setAttribute("flex", "1");
            textbox_minor.setAttribute("id", id + "_" + n[1]);
            hbox.appendChild(textbox_minor);
            var textbox_build = document.createElement("textbox");
            textbox_build.setAttribute("type", "number");
            textbox_build.setAttribute("value", v[2]);
            textbox_build.setAttribute("min", "0");
            textbox_build.setAttribute("max", "9999");
            textbox_build.setAttribute("flex", "1");
            textbox_build.setAttribute("id", id + "_" + n[2]);
            hbox.appendChild(textbox_build);
            document.getElementById(container).appendChild(hbox);
        }
        else if(typeof(data[i]) == "string" || typeof(data[i]) == "number")
        {
            var w = 110 + ind;
            var hbox = document.createElement('hbox');
            hbox.setAttribute("flex", "1");
            hbox.setAttribute("align", "center");
            hbox.setAttribute("style", "border-bottom:1px solid #FFFFFF;border-top:1px solid #D4D4D4;");
            var label = document.createElement('label');
            label.setAttribute("value", indChar + i);
            label.setAttribute("style", "height:15px;width:" + w + "px;color:#000;");
            var textbox = document.createElement('textbox');
            textbox.setAttribute("value", data[i]);
            textbox.setAttribute("id", id);
            textbox.setAttribute("style", "height:15px;");
            textbox.setAttribute("flex", "1");
            hbox.appendChild(label);
            hbox.appendChild(textbox);
            document.getElementById(container).appendChild(hbox);
        }
        else if(typeof(data[i]) == "boolean")
        {
            var w = 110 + ind;
            var hbox = document.createElement("hbox");
            hbox.setAttribute("flex", "1");
            hbox.setAttribute("align", "center");
            hbox.setAttribute("style", "border-bottom:1px solid #FFFFFF;border-top:1px solid #D4D4D4;");
            var label = document.createElement("label");
            label.setAttribute("style", "height:15px;width:" + w + "px;");
            label.setAttribute("value", indChar + i);
            var menulist = document.createElement("menulist");
            menulist.setAttribute("style", "height:15px;");
            menulist.setAttribute("flex", "1");
            menulist.setAttribute("id", id);
            var menupopup = document.createElement("menupopup");
            var menuitem1 = document.createElement("menuitem");
            menuitem1.setAttribute("label", "true");
            menuitem1.setAttribute("value", "true");
            if(data[i] == true)
                menuitem1.setAttribute("selected", "true");
            var menuitem2 = document.createElement("menuitem");
            menuitem2.setAttribute("label", "false");
            menuitem2.setAttribute("value", "false");
            if(data[i] == false)
                menuitem2.setAttribute("selected", "true");
            menupopup.appendChild(menuitem1);
            menupopup.appendChild(menuitem2);
            menulist.appendChild(menupopup);
            hbox.appendChild(label);
            hbox.appendChild(menulist);
            document.getElementById(container).appendChild(hbox);
        }
        else if(typeof(data[i]) == "object")
        {
            ko.extensions.webos.json._objIndent++;
            var hbox = document.createElement("hbox");
            hbox.setAttribute("style", "border-bottom:1px solid #FFFFFF;border-top:1px solid #D4D4D4;");
            var label = document.createElement("label");
            if(isNaN(i))
                label.setAttribute("value", indChar + i);
            else
                label.setAttribute("value", indChar + "index: " + i);
            hbox.appendChild(label);
            document.getElementById(container).appendChild(hbox);
            edit[i].ns = id;
            ko.extensions.webos.json.createInputs(data[i], edit[i]);
            ko.extensions.webos.json._objIndent--;
        }
    }
};